//-----------------------------------------------------------------------------
// AddMandatoryAccountCode
//
// Copyright (c) MetaSwitch 2006
// Author: Alex Davies
//
// Sample application demonstrating the SOAP Sh interface to the MetaView
// Server.  This application sends in an Sh-Pull request to get the Mandatory
// Account Codes configured for a Business Group, and an Sh-Update request to
// add a new one.  It uses Apache Axis and the "typed" WSDL file and also
// demonstrates use of the sequence number.
//
// See the readme file for more information.
//-----------------------------------------------------------------------------

import javax.xml.rpc.holders.*;

import java.util.*;

import com.MetaSwitch.EMS.SOAP.*;
import com.MetaSwitch.EMS.SOAP.holders.*;

public class AddMandatoryAccountCode
{
  private final static String USAGE = "Usage: AddMandatoryAccountCode " +
                                      "<MetaSwitch name> <Business Group " +
                                      "name> <New account code> " +
                                      "[<Description>]";

  private static ShTypedUtilities utilities = new ShTypedUtilities();

  public static void main(String[] args)
  {
    StringHolder metaSwitchHolder = new StringHolder();
    StringHolder businessGroupHolder = new StringHolder();
    StringHolder codeHolder = new StringHolder();
    StringHolder descriptionHolder = new StringHolder();

    IntHolder resultCodeHolder = new IntHolder();
    TExtendedResultHolder extendedResultHolder = new TExtendedResultHolder();
    TUserDataHolder userDataHolder = new TUserDataHolder();

    try
    {
      //-----------------------------------------------------------------------
      // Extract information from the command line arguments.
      //-----------------------------------------------------------------------
      getParameters(args,
                    metaSwitchHolder,
                    businessGroupHolder,
                    codeHolder,
                    descriptionHolder);

      String[] identifiers = new String[]
                         { metaSwitchHolder.value, businessGroupHolder.value };
      String userIdentity = utilities.getUserIdentity(identifiers);

      //-----------------------------------------------------------------------
      // Connect to the Sh service, and retrieve and display the current
      // account codes.
      //-----------------------------------------------------------------------
      ShServiceLocator locator = new ShServiceLocator();

      Sh shInstance = locator.getShService();

      shInstance.shPull(userIdentity,
                        0,
                        "Meta_BusinessGroup_MandatoryAccountCodes",
                        utilities.ORIGIN_HOST,
                        resultCodeHolder,
                        extendedResultHolder,
                        userDataHolder);

      utilities.checkResultCode(resultCodeHolder.value,
                                extendedResultHolder.value,
                                userDataHolder.value);

      System.out.println("Current Mandatory Account Codes:");

      TMeta_BusinessGroup_MandatoryAccountCodes macFieldGroup =
                  userDataHolder.value
                                .getShData()
                                .getRepositoryData()
                                .getServiceData()
                                .getMetaSwitchData()
                                .getMeta_BusinessGroup_MandatoryAccountCodes();

      TValidAccountCodesAccountCode[] currentCodes =
                                          macFieldGroup.getValidAccountCodes();

      System.out.println(tabulateCodes(currentCodes));

      //-----------------------------------------------------------------------
      // Update the userData with the incremented sequence number and add the
      // extra account code.
      //-----------------------------------------------------------------------
      utilities.incrementSequenceNumber(userDataHolder.value);

      TValidAccountCodesAccountCode newCode =
                    new TValidAccountCodesAccountCode(codeHolder.value,
                                                      descriptionHolder.value);

      TValidAccountCodesAccountCode[] newCodes =
                    new TValidAccountCodesAccountCode[currentCodes.length + 1];
      System.arraycopy(currentCodes, 0, newCodes, 0, currentCodes.length);
      newCodes[newCodes.length - 1] = newCode;

      macFieldGroup.setValidAccountCodes(newCodes);

      //-----------------------------------------------------------------------
      // Send it in as an Sh-Update request, and make sure it succeeded.
      //-----------------------------------------------------------------------
      shInstance.shUpdate(userIdentity,
                          0,
                          userDataHolder.value,
                          utilities.ORIGIN_HOST,
                          resultCodeHolder,
                          extendedResultHolder);

      utilities.checkResultCode(resultCodeHolder.value,
                                extendedResultHolder.value,
                                userDataHolder.value);

      //-----------------------------------------------------------------------
      // Get and show the current account codes again to confirm they have
      // changed.
      //-----------------------------------------------------------------------
      shInstance.shPull(userIdentity,
                        0,
                        "Meta_BusinessGroup_MandatoryAccountCodes",
                        utilities.ORIGIN_HOST,
                        resultCodeHolder,
                        extendedResultHolder,
                        userDataHolder);

      utilities.checkResultCode(resultCodeHolder.value,
                                extendedResultHolder.value,
                                userDataHolder.value);

      System.out.println("New Mandatory Account Codes:");

      currentCodes = userDataHolder
                     .value
                     .getShData()
                     .getRepositoryData()
                     .getServiceData()
                     .getMetaSwitchData()
                     .getMeta_BusinessGroup_MandatoryAccountCodes()
                     .getValidAccountCodes();

      System.out.println(tabulateCodes(currentCodes));
    }
    catch (MetaSwitchShInterfaceException e)
    {
      System.err.println(e.getMessage());
      System.err.println(USAGE);
    }
    catch (org.apache.axis.AxisFault e)
    {
      System.err.println("Problem connecting to MetaView server: " + e);
      System.err.println(USAGE);
    }
    catch (javax.xml.rpc.ServiceException e)
    {
      System.err.println("Could not connect to Sh service");
      System.err.println(USAGE);
    }
    catch (Exception e)
    {
      System.err.println("Unexpected error \"" + e
                         + "\" in retrieving data");
      e.printStackTrace(System.err);
      System.err.println(USAGE);
    }
  }

  /**
   * Parse the command line arguments and extract the necessary information.
   *
   * @param args        IN  The arguments provided at the command line.
   * @param metaSwitch
   *                    OUT The name of the MetaSwitch on which the BG resides.
   * @param businessGroup
   *                    OUT The name of the Business Group to update.
   * @param code        OUT The new code to create.
   * @param description
   *                    OUT The description of this new code.
   *
   * @exception WrongParametersException
   */
  private static void getParameters(String[] args,
                                    StringHolder metaSwitch,
                                    StringHolder businessGroup,
                                    StringHolder code,
                                    StringHolder description)
    throws WrongParametersException
  {
    if ((args.length < 3) || (args.length > 4))
    {
      throw new WrongParametersException("Wrong number of parameters.");
    }

    metaSwitch.value = args[0];
    businessGroup.value = args[1];
    code.value = args[2];
    description.value = (args.length == 4 ? args[3] : null);
  }

  /**
   * Produce a human-readable representation of the mandatory account codes.
   *
   * @returns           A string representation of the account codes.
   *
   * @param codes       A set of Mandatory Account Codes.
   */
  private static String tabulateCodes(TValidAccountCodesAccountCode[] codes)
  {
    StringBuilder tabulatedCodesBuilder = new StringBuilder();

    for (TValidAccountCodesAccountCode code : codes)
    {
      //-----------------------------------------------------------------------
      // Add this account code to the string representation of the Mandatory
      // Account Codes table.
      //-----------------------------------------------------------------------
      tabulatedCodesBuilder.append(code.getCode());
      if (code.getDescription() != null)
      {
        //---------------------------------------------------------------------
        // There is a description, so add it to the table.
        //---------------------------------------------------------------------
        tabulatedCodesBuilder.append(" ");
        tabulatedCodesBuilder.append(code.getDescription());
      }
      tabulatedCodesBuilder.append("\n");
    }

    return tabulatedCodesBuilder.toString();
  }
}
